package net.oschina.esb.core;

import net.oschina.esb.core.env.EsbContext;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.BeansException;
import org.springframework.beans.factory.support.BeanDefinitionRegistry;
import org.springframework.context.ApplicationContext;
import org.springframework.context.ApplicationContextAware;
import org.springframework.context.EnvironmentAware;
import org.springframework.context.annotation.ImportBeanDefinitionRegistrar;
import org.springframework.core.env.Environment;
import org.springframework.core.type.AnnotationMetadata;

import java.util.HashMap;
import java.util.Map;

/**
 * @author Arvin
 * @time 2018/4/11 21:47
 */
public abstract class AbstractSpringBootRegister implements ImportBeanDefinitionRegistrar, EnvironmentAware, ApplicationContextAware {

    protected final Logger logger = LoggerFactory.getLogger(getClass());

    protected static Map<Class<?>, Boolean> hadInInitMap = new HashMap<>();

    protected Environment environment;

    protected ApplicationContext applicationContext;

    @Override
    public void setApplicationContext(ApplicationContext applicationContext) throws BeansException {
        EsbContext.setApplicationContext(applicationContext);
        this.applicationContext = applicationContext;
    }

    @Override
    public void setEnvironment(Environment environment) {
        EsbContext.setEnvironment(environment);
        this.environment = environment;
    }

    @Override
    public final void registerBeanDefinitions(AnnotationMetadata importingClassMetadata, BeanDefinitionRegistry registry) {

        // 保证只初始化一次
        Class<?> clazz = getClass();
        synchronized (clazz) {
            Boolean hadInInit = hadInInitMap.get(clazz);
            if (null != hadInInit) {
                return;
            }
            hadInInitMap.put(clazz, true);
        }

        registerBeanDefinitions(importingClassMetadata, registry, environment, applicationContext);
    }

    protected String getAppProperty(String key, String defaultValue) {
        return EsbContext.getAppProperty(environment, key, defaultValue);
    }

    /**
     * 注册 BeanDefinition
     */
    public abstract void registerBeanDefinitions(AnnotationMetadata importingClassMetadata, BeanDefinitionRegistry registry, Environment environment, ApplicationContext applicationContext);
}
